package demo01;

import java.io.FileNotFoundException;
import java.io.IOException;

/*
 *  异常处理的第一种方式：
 *  throws关键字：声明异常，将异常标识出来，交给调用者处理
 *  作用：
 *      当方法内部出现异常对象，就必须对该异常对象进行处理
 *      使用throws关键字处理异常对象，会将异常对象声明，并抛出给方法的调用者（自己不会进行异常处理，而交给别人处理）
 *      如果方法的调用者继续使用throws抛出异常对象，最终会将异常交给JVM处理，即中断处理
 *  使用格式：
 *      修饰符 返回值类型 方法名(参数列表) throws AAAException, BBBException, ... {
 *          throw new AAAException("A异常提示信息");
 *          throw new BBBException("B异常提示信息");
 *          ...
 *      }
 *  注意事项：
 *      1. throws关键字必须写在方法声明处
 *      2. throws关键字后声明的异常必须是Exception或者Exception的子类
 *      3. 方法内部如果抛出了多个异常，那么throws后也必须声明多个异常
 *          如果抛出的异常之间有子父类关系，那么直接声明父类异常即可
 *      4. 调用了一个声明抛出异常的方法，就必须处理声明的异常
 *          要么继续使用throws声明抛出，交给方法的调用者处理，最终交给JVM处理
 *          要么使用try...catch手动捕获处理异常
 */
public class Demo05Throws {
    public static void main(String[] args) throws IOException {
        readFile("C:\\a.txt"); // 文件读取成功
        readFile("d:\\a.txt"); // FileNotFoundException: 文件路径不在c盘，请传递c盘下的文件
        readFile("c:\\a.jpg"); // IOException: 文件的后缀名不对，请传递txt文件
    }

    /*
     *  定义一个方法，读取文件，并对该文件的路径进行合法性判断
     *  抛出异常：FileNotFoundException可以省略，因为IOException是其父类，抛出父类异常后就无需抛出其子类
     */
    private static void readFile(String filename) throws IOException /*, FileNotFoundException */ {
        /*
         *  如果路径不在'c'或'C'路径下，就抛出未找到文件异常，并将错误信息告知调用者
         *  注意：FileNotFoundException是编译异常，抛出了编译异常就必须进行处理，可以继续使用throws抛出该异常让方法调用者处理
         */
        if (!(filename.charAt(0) == 'c' || filename.charAt(0) == 'C')) { // 首字符如果不是c盘，抛出未找到文件异常
            throw new FileNotFoundException("文件路径不在c盘，请传递c盘下的文件");
        }

        /*
         *  如果路径不是以".txt"结尾，就抛出IO异常，并将错误信息告知调用者
         *  注意：IOException是FileNotFoundException的父类，因此抛出异常时，可以只抛出父类异常IOException
         */
        // endsWith方法：测试调用者字符串是否以此参数字符串为后缀结束，是则返回true，不是则返回false
        if(!filename.endsWith(".txt")) { // 字符串结尾如果不是txt，抛出IO流异常
            throw new IOException("文件的后缀名不对，请传递txt文件");
        }

        System.out.println("文件读取成功");
    }
}
